/**
 * \file  debugging.cpp
 * \brief Definition of Debugging implementation class.
 *
 * LAV: Lib Anti Virals
 * <http://lav.googlecode.com/>
 * Copyright (C) 2013 Boretto Martin, Lenarduzzi Federico,
 *                    Alberione Fernando, Ocampo Emanuel FuDePAN
 *
 * This file is part of the LAV project.
 *
 * Contents:       Cpp file for LAV providing class Debugging implementation.
 *
 * System:         LAV
 * Language:       C++
 *
 * Author:         Boretto Martin
 * E-Mail:         martinboretto@gmail.com
 *
 * Author:         Lenarduzzi Federico
 * E-Mail:         federicolenarduzzi@gmail.com
 *
 * Author:         Alberione Fernando
 * E-Mail:         falberione037@gmail.com
 *
 * Author:         Ocampo Emanuel
 * E-Mail:         eocampo86@gmail.com
 *
 * LAV is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * LAV is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LAV.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "lav/debugging.h"

using namespace std;

namespace lav
{

void Debugging::print_antivirals(const AntiviralSet& avrs) const
{
    clog << "\n\n = PRE-PROCESSING (AProba Algorithm - STEP 1) \n" << endl;
    for (AVIterator it = avrs.begin_AVIterator(); !it.end(); ++it)
    {
        (*it)->print_antiviral();
    }
}


void Debugging::print_all_combinations(const ResisBasedAntiviral::CombinationContainer& arvs_info, bool is_arvs_x) const
{

    if (is_arvs_x)
        // Print combinations with cartesian product applied
        print_combinations_with_x(arvs_info);
    else
        // Print combinations without cartesian product applied
        print_only_combinations(arvs_info);
}


void Debugging::print_expansions(const ARVExpansionContainer& arvs_expansion, bool is_arvs_x) const
{
    int i;
    ARVExpansionContainer::const_iterator it_comb_exp;
    if (is_arvs_x)
    {
        i = 1;
        clog << "\n\n = CARTESIAN PRODUCT IN NUCLEOTIDS EXPANSION (AProba Algorithm - STEP 5) \n" << endl;
        for (it_comb_exp = arvs_expansion.begin(); it_comb_exp != arvs_expansion.end(); ++it_comb_exp)
        {
            ARVExpansion::const_iterator it_second;
            ARVExpansion second = (*it_comb_exp);
            for (it_second = second.begin(); it_second != second.end(); ++it_second)
            {
                AminoacidExpansion::const_iterator it_first;
                AminoacidExpansion first = (*it_second);
                clog << "(" << i << ") | ";
                for (it_first = first.begin(); it_first != first.end(); ++it_first)
                {
                    clog << "(" << it_first->pos << ", " << (it_first->triplet).to_string() << ")";
                }
                clog << endl;
                ++i;
            }
        }
    }
    else
    {
        clog << "\n\n = EXPANSION IN NUCLEOTIDS (AProba Algorithm - STEP 4) \n" << endl;
        for (it_comb_exp = arvs_expansion.begin(); it_comb_exp != arvs_expansion.end(); ++it_comb_exp)
        {
            ARVExpansion::const_iterator it_second;
            ARVExpansion second = (*it_comb_exp);
            for (it_second = second.begin(); it_second != second.end(); ++it_second)
            {
                AminoacidExpansion::const_iterator it_first;
                AminoacidExpansion first = (*it_second);
                for (it_first = first.begin(); it_first != first.end(); ++it_first)
                {
                    clog << "(" << it_first->pos << ", " << (it_first->triplet).to_string() << ")";
                }
                clog << "  ;  ";
            }
            clog << endl;
        }
    }
}


void Debugging::print_combinations_with_genetic_distances(const CombinationDistanceContainer& combinations_with_distances, bool is_ranker) const
{
    int i;
    i = 1;
    CombinationDistanceContainer::const_iterator it_comb_distances;

    if (is_ranker)
        clog << "\n\n = EXPANSION IN NUCLEOTIDS WITH GENETIC DISTANCES REDUCE ACCORDING TO A TOLERANCE (RANKER) (AProba Algorithm - STEP 7) \n" << endl;
    else
        clog << "\n\n = EXPANSION IN NUCLEOTIDS WITH GENETIC DISTANCES (AProba Algorithm - STEP 6) \n" << endl;

    for (it_comb_distances = combinations_with_distances.begin(); it_comb_distances != combinations_with_distances.end(); ++it_comb_distances)
    {
        AminoacidExpansion::const_iterator it_combinations;
        AminoacidExpansion combinations = it_comb_distances->triplets_combinations;
        clog << "(" << i << ") | ";
        for (it_combinations = combinations.begin(); it_combinations != combinations.end(); ++it_combinations)
        {
            clog << "(" << it_combinations->pos << ", " << (it_combinations->triplet).to_string() << ")";
        }
        clog << " - " << it_comb_distances->distance;
        clog << endl;
        ++i;
    }
}


void Debugging::print_all_mutants(const MutantContainer& mutants_list) const
{
    MutantContainer::const_iterator it_mutants;
    int current_combination = 1;
    clog << "\n\n = MUTANTS GENERATION (AProba Algorithm - STEP 8) \n" << endl;
    for (it_mutants = mutants_list.begin(); it_mutants != mutants_list.end(); ++it_mutants)
    {
        clog << "Mutant: " << current_combination << " ==> " << it_mutants->second << "\n" << endl;
        ++current_combination;
    }
}


void Debugging::print_combinations_with_x(const ResisBasedAntiviral::CombinationContainer& arvs_info_x) const
{
    int comb_index = 1;
    ResisBasedAntiviral::CombinationContainer:: const_iterator it_comb_cont;
    clog << "\n\n = CARTESIAN PRODUCT (AProba Algorithm - STEP 3) \n" << endl;
    for (it_comb_cont = arvs_info_x.begin(); it_comb_cont != arvs_info_x.end(); ++it_comb_cont)
    {
        clog << "-- Combination " << comb_index << "--" << endl;
        ResisBasedAntiviral::Combination::const_iterator it_comb;
        ResisBasedAntiviral::Combination current_combination = (*it_comb_cont);

        for (it_comb = current_combination.begin(); it_comb != current_combination.end(); ++it_comb)
        {
            ResisBasedAntiviral::ResistancePositionContainer::const_iterator it_resistances;
            ResisBasedAntiviral::ResistancePositionContainer current_resistance = (*it_comb);

            for (it_resistances = current_resistance.begin(); it_resistances != current_resistance.end(); ++it_resistances)
            {
                clog << "(" << it_resistances->pos << "," << it_resistances->aminoacids << ", " << it_resistances->weight << ")";
            }
            clog << ";";
        }
        clog << "\n" << endl;
        ++comb_index;
    }
}


void Debugging::print_only_combinations(const ResisBasedAntiviral::CombinationContainer& arvs_info) const
{
    int comb_index = 1;
    ResisBasedAntiviral::CombinationContainer:: const_iterator it_comb_cont;
    clog << "\n\n = POWER_SET PARTITIONS (AProba Algorithm - STEP 2) \n" << endl;
    for (it_comb_cont = arvs_info.begin(); it_comb_cont != arvs_info.end(); ++it_comb_cont)
    {
        // Print combinations without cartesian product
        clog << "-- Antiviral " << comb_index << "--" << endl;
        ResisBasedAntiviral::Combination::const_iterator it_comb;
        ResisBasedAntiviral::Combination current_combination = (*it_comb_cont);

        for (it_comb = current_combination.begin(); it_comb != current_combination.end(); ++it_comb)
        {
            clog << "-- Group --" << endl;
            ResisBasedAntiviral::ResistancePositionContainer::const_iterator it_resistances;
            ResisBasedAntiviral::ResistancePositionContainer current_resistance = (*it_comb);

            for (it_resistances = current_resistance.begin(); it_resistances != current_resistance.end(); ++it_resistances)
            {
                clog << "(" << it_resistances->pos << "," << it_resistances->aminoacids << ", " << it_resistances->weight << ")";
            }
            clog << endl;
        }
        ++comb_index;
    }
}

}